use bevy::prelude::*;

use crate::{
    game::planting::{component::*, event::*, resource::*},
    persistence::Saved,
};

use super::SavedGame;

pub fn save_game_obs(
    _: Trigger<ESaveGame>,
    planting_day: ResMut<PlantingDay>,
    crop_query: Query<(&CropComponent, &BlockMapPos, &CropConfigComponent)>,
    water_pos_query: Query<&BlockMapPos, With<WaterComponent>>,
    field_pos_query: Query<&BlockMapPos, With<FieldComponent>>,
    furniture_query: Query<(&FurnitureComponent, &BlockMapPos)>,
    bag_goods_query: Query<(&BackpackIndexComponent, Option<&GoodsComponent>)>,
    fast_bag_goods_query: Query<
        (&FastListIndexComponent, Option<&GoodsComponent>),
        Without<BackpackIndexComponent>,
    >,
) {
    let saved_game = SavedGame {
        is_first: false,
        bag: bag_goods_query
            .iter()
            .map(|(index, item)| {
                if let Some(item) = item {
                    (index.index, Some((item.goods_item.clone(), item.count)))
                } else {
                    (index.index, None)
                }
            })
            .collect(),
        fast: fast_bag_goods_query
            .iter()
            .map(|(index, item)| {
                if let Some(item) = item {
                    (index.index, Some((item.goods_item.clone(), item.count)))
                } else {
                    (index.index, None)
                }
            })
            .collect(),
        planting_day: planting_day.clone(),
        crop: crop_query
            .iter()
            .map(|(crop, pos, config)| (crop.clone(), pos.clone(), config.clone()))
            .collect(),
        field: field_pos_query.iter().map(|pos| pos.clone()).collect(),
        water: water_pos_query.iter().map(|pos| pos.clone()).collect(),
        furniture: furniture_query
            .iter()
            .map(|(furniture, pos)| (furniture.clone(), pos.clone()))
            .collect(),
    };
    saved_game.save();
    println!("保存游戏成功！");
}

///加载游戏数据
pub fn load_game_data(mut commands: Commands) {
    //加载游戏数据
    let game_data = SavedGame::load();
    commands.insert_resource(game_data);
}

pub fn init_game_data(
    mut commands: Commands,
    mut planting_day: ResMut<PlantingDay>,
    saved_game: Res<SavedGame>,
) {
    planting_day.day = saved_game.planting_day.day;
    planting_day.time = saved_game.planting_day.time;
    for pos in &saved_game.field {
        commands.trigger(EHoeField {
            pos: pos.clone().into(),
        });
    }

    for (component, pos, config) in &saved_game.crop {
        commands.trigger(EPlantCrop {
            pos: pos.clone().into(),
            day: component.day,
            curr_stages: component.curr_stages,
            seed_item: config.0.clone(),
            is_consume: false,
        });
    }
    for pos in &saved_game.water {
        commands.trigger(EWaterCrop {
            pos: pos.clone().into(),
        });
    }
    for (component, pos) in &saved_game.furniture {
        commands.trigger(EPutFurniture {
            pos: pos.clone().into(),
            furniture_component: component.clone(),
            is_consume: false,
        });
    }
    for (index, item) in saved_game.bag.iter() {
        let index = *index;
        if let Some(item) = item {
            commands.spawn((
                GoodsComponent {
                    goods_item: item.0.clone(),
                    count: item.1,
                },
                BackpackIndexComponent { index },
            ));
        } else {
            commands.spawn(BackpackIndexComponent { index });
        }
    }
    for (index, item) in saved_game.fast.iter() {
        let index = *index;
        if let Some(item) = item {
            commands.spawn((
                GoodsComponent {
                    goods_item: item.0.clone(),
                    count: item.1,
                },
                FastListIndexComponent { index },
            ));
        } else {
            commands.spawn(FastListIndexComponent { index });
        }
    }
    if saved_game.is_first {
        commands.trigger(EFirstLoadGame);
    }
}
